package com.corpgovernment.permission.service;

import com.corpgovernment.api.organization.model.backuser.BackgroundUserVo;
import com.corpgovernment.api.organization.model.bookingrelation.UidOrgIdEntry;
import com.corpgovernment.api.organization.model.user.employee.OrgPostLogVo;
import com.corpgovernment.api.organization.model.user.login.MbUserLoginVo;
import com.corpgovernment.api.organization.soa.IBackgroundUserClient;
import com.corpgovernment.api.permission.vo.*;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.utils.Null;

import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.permission.Config;
import com.corpgovernment.permission.MenuConverter;
import com.corpgovernment.organization.metric.MetricService;
import com.corpgovernment.permission.Config;
import com.corpgovernment.permission.MenuConverter;
import com.corpgovernment.permission.entity.db.*;
import com.corpgovernment.permission.mapper.*;
import com.corpgovernment.permission.utils.PermissionRedisUtil;
import com.corpgovernment.redis.cache.RedisUtils;
import com.ctrip.corp.obt.generic.core.context.TenantContext;
import com.corpgovernment.organization.constant.PermissionConstant;
import com.corpgovernment.organization.constant.RedisCacheTimeConst;
import com.corpgovernment.organization.entity.db.MbOrgInfo;
import com.corpgovernment.organization.service.IOrganizationEmployeeService;
import com.corpgovernment.organization.service.IOrganizationInfoService;
import com.corpgovernment.organization.service.IUserLoginService;
import com.corpgovernment.organization.service.impl.BackgroundUserService;
import com.corpgovernment.permission.entity.db.MbRole;
import com.corpgovernment.permission.entity.db.MbRolePermission;
import com.corpgovernment.permission.entity.db.MbUserRole;
import com.corpgovernment.permission.mapper.RoleMapper;
import com.corpgovernment.permission.mapper.RolePermissionMapper;
import com.corpgovernment.permission.mapper.UserRoleMapper;
import com.corpgovernment.redis.handler.RedisHandler;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.ParameterizedType;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.corpgovernment.organization.metric.MetricService.ORGANIZATION_MANAGE_MENU_USE;

@Service
@Slf4j
public class UserService {
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private MenuTempMapper menuTempMapper;
    @Autowired
    private IOrganizationEmployeeService organizationEmployeeService;
    @Autowired
    private IOrganizationInfoService organizationInfoService;
    @Autowired
    private IBackgroundUserClient backgroundUserSoaService;
    @Autowired
    private BackgroundUserService backgroundUserService;
    @Autowired
    private IUserLoginService userLoginService;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private PermissionRedisUtil permissionRedisUtil;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RedisHandler redisHandler;
    private static final String URL_SPLIT = "\\|";


    public List<UserMenuTo> findDataPermission() {
        List<Menu> menuList = getAllPermission();
        menuList = menuList.stream().filter(t->t.getDataPermission() != null && t.getDataPermission() != 0).collect(Collectors.toList());
        return builderUserMenuTree(menuList);
    }


    public List<String> getUserPermissionUrlList(GetUserPermissionListRequest req) {
        List<Menu> menuList = getPermission(req.getUid(), false);
        List<String> urlList = new ArrayList<>();
        menuList.forEach(t -> {
            if (CollectionUtils.isNotEmpty(t.getServiceUrlList())) {
                urlList.addAll(t.getServiceUrlList());
            }
        });
        return urlList.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
    }

    /**
     * uid获取所拥有的权限的菜单
     */
    public List<Menu> getPermission(String uid, Boolean isAdmin) {
        if (StringUtils.isBlank(uid)) {
            return Collections.emptyList();
        }
        if(isAdmin) {
            Map<String, Menu> cachedPermission = getAllPermissionMap();
            if (CollectionUtils.isEmpty(cachedPermission)){
                return Collections.emptyList();
            }
            return new ArrayList<>(cachedPermission.values());
        }
        // 获取uid对应的roleId列表
        List<Long> roleList = queryUidRoles(uid);
        // 获取roleId列表对应的权限
        List<Long> rolePermissionList = queryRolePermission(roleList);
        // 从公共域拉取数据
        Map<String, Menu> cachedPermission = getAllPermissionMap();

        List<Menu> urlList = new ArrayList<>();
        rolePermissionList.forEach(t -> {
            Menu hasPermission = cachedPermission.get(Null.or(t,String::valueOf,"0"));
            if (hasPermission != null){
                urlList.add(hasPermission);
            }
        });
        return urlList;
    }

    public List<Menu> getAllPermission() {
        try {
            // 从公共域拉取数据
            List<Menu> cachedPermission = TenantContext.ignoreTenantContext(() -> redisUtils.getCacheList(PermissionConstant.PERMISSION_LIST_PREFIX, Menu.class));
            if (CollectionUtils.isEmpty(cachedPermission)) {
                try {
                    Thread.sleep(10);
                } catch (Exception e) {
                    log.info("线程阻塞异常", e);
                }
                cachedPermission = TenantContext.ignoreTenantContext(() -> redisUtils.getCacheList(PermissionConstant.PERMISSION_LIST_PREFIX, Menu.class));
            }
            if (CollectionUtils.isEmpty(cachedPermission)) {
                cachedPermission = queryMenuListFromDb();
                if (CollectionUtils.isEmpty(cachedPermission)) {
                    return Collections.emptyList();
                }
                Map<String, Menu> map = cachedPermission.stream().collect(Collectors.toMap(t -> String.valueOf(t.getId()), Function.identity()));
                List<Menu> finalCachedPermission = cachedPermission;
                TenantContext.ignoreTenantContext(() -> {
                            redisUtils.delete(PermissionConstant.PERMISSION_LIST_PREFIX);
                            redisUtils.setList(PermissionConstant.PERMISSION_LIST_PREFIX, finalCachedPermission, 60 * 60 * 24 * 180);
                            redisUtils.delete(PermissionConstant.PERMISSION_MAP_PREFIX);
                            redisUtils.setHash(PermissionConstant.PERMISSION_MAP_PREFIX, map, 60 * 60 * 24 * 180);
                        }
                );
            }
            return cachedPermission;
        } catch (Exception e) {
            log.error("getAllPermission error", e);
            MetricService.metricMenuCounter(ORGANIZATION_MANAGE_MENU_USE, false);
        }
        return Collections.emptyList();
    }

    public List<String> getAllUrlList() {
        // 从公共域拉取数据
        List<Menu> menuList = this.getAllPermission();
        if (CollectionUtils.isEmpty(menuList)){
            return Collections.emptyList();
        }
        return menuList.stream().filter(Objects::nonNull).map(Menu::getKey).filter(StringUtils::isNotBlank).collect(Collectors.toList());
    }
    public Map<String,Menu> getAllPermissionMap() {
        // 从公共域拉取数据
        Map<String, Menu> cachedPermission = TenantContext.ignoreTenantContext(() -> permissionRedisUtil.getCacheHash(PermissionConstant.PERMISSION_MAP_PREFIX, Menu.class));
        if (CollectionUtils.isEmpty(cachedPermission)) {
            try {
                Thread.sleep(10);
            } catch (Exception e) {
                log.info("线程阻塞异常", e);
            }
            cachedPermission = TenantContext.ignoreTenantContext(() -> permissionRedisUtil.getCacheHash(PermissionConstant.PERMISSION_MAP_PREFIX, Menu.class));
        }
        if(CollectionUtils.isEmpty(cachedPermission)) {
            cachedPermission = queryMenuMapFromDb();
        }

        return cachedPermission;
    }


    /**
     * 获取uid和角色的映射关系
     * 先从redis中拿，拿不到到DB里拿再刷新缓存
     *
     * @param uid
     * @return
     */
    private List<Long> queryUidRoles(String uid) {
        Object uidRoleRelationship = redisHandler.getValue(PermissionConstant.UID_ROLE_RELATION + uid);
        // 缓存里没有从DB里取
        if (uidRoleRelationship == null) {
            Example example = new Example(MbUserRole.class);
            example.createCriteria().andEqualTo("uid", uid);
            List<MbUserRole> mbUserRoleList = userRoleMapper.selectByExample(example);
            if (CollectionUtils.isNotEmpty(mbUserRoleList)) {
                List<Long> roleList = mbUserRoleList.stream().map(MbUserRole::getRoleId).collect(Collectors.toList());
                Example mbRoleExample = new Example(MbRole.class);
                mbRoleExample.createCriteria().andIn("id", roleList);
                List<MbRole> mbRoles = roleMapper.selectByExample(mbRoleExample);
                List<Long> roleParentList = mbRoles.stream().map(MbRole::getParentId).filter(Objects::nonNull).collect(Collectors.toList());
                roleList.addAll(roleParentList);
                roleList = roleList.stream().distinct().collect(Collectors.toList());
                // 将uid对应的角色存入
                redisHandler.setValue(PermissionConstant.UID_ROLE_RELATION + uid, roleList, RedisCacheTimeConst.DEFAULT_CACHE_SECONDS);
                return roleList;
            }
            return Collections.emptyList();
        }
        // 从redis取出的数字数据类型都是Integer，所以做了强转
        return ((List<Integer>) uidRoleRelationship).
                stream().map(Long::valueOf).collect(Collectors.toList());
    }

    /**
     * 获角色和权限的映射关系
     * 先从redis中拿，拿不到到DB里拿再刷新缓存
     */
    private List<Long> queryRolePermission(List<Long> roleIdList) {
        // 判空
        if (CollectionUtils.isEmpty(roleIdList)) {
            return Collections.emptyList();
        }
        List<Long> rolePermissionList = new ArrayList<>();
        // 获取roleId所拥有的权限
        roleIdList.forEach(roleId -> {
            Object roleIdPermissionRelation = redisHandler.getValue(PermissionConstant.ROLE_PERMISSION_RELATION + roleId);
            // 单个角色的权限list
            List<Long> singleRolePermission;
            if (roleIdPermissionRelation == null) {
                // 刷新缓存
                singleRolePermission = queryRolePermissionFromDB(roleId);
                redisHandler.delete(PermissionConstant.ROLE_PERMISSION_RELATION + roleId);
                redisHandler.setValue(PermissionConstant.ROLE_PERMISSION_RELATION + roleId,
                        singleRolePermission,
                        RedisCacheTimeConst.DEFAULT_CACHE_SECONDS);
            } else {
                // 对缓存内取出的数据进行强转
                singleRolePermission = ((List<Integer>) roleIdPermissionRelation)
                        .stream()
                        .filter(Objects::nonNull)
                        .map(Long::valueOf)
                        .collect(Collectors.toList());
            }
            rolePermissionList.addAll(singleRolePermission);
        });
        // 去重
        return rolePermissionList.stream().distinct().collect(Collectors.toList());
    }

    private List<Long> queryRolePermissionFromDB(long roleId) {
        List<MbRolePermission> mbRolePermissionList = rolePermissionMapper.listByRoleId(roleId);
        return mbRolePermissionList.stream()
                .map(MbRolePermission::getPermissionId)
                .collect(Collectors.toList());
    }

    private Map<String, Menu> queryMenuMapFromDb(){
        String menuId = Config.defaultConfig().get("menuId");
        List<Menu> list = null;
        if(StringUtils.isBlank(menuId)){
            list = TenantContext.ignoreTenantContext(() -> {
                MenuTemp menuTemp = menuTempMapper.getLastRecord();
                return JsonUtils.parse(menuTemp.getMenuJson(), new TypeReference<List<Menu>>() {
                });
            });
        } else {
            list = TenantContext.ignoreTenantContext(() -> {
                MenuTemp menuTemp = menuTempMapper.selectByPrimaryKey(Long.parseLong(menuId));
                return JsonUtils.parse(menuTemp.getMenuJson(), new TypeReference<List<Menu>>() {
                });
            });
        }
        Map<String, Menu> map = list.stream().collect(Collectors.toMap(t->String.valueOf(t.getId()),Function.identity()));
        return map;
    }
    private List<Menu> queryMenuListFromDb(){
        String menuId = Config.defaultConfig().get("menuId");
        List<Menu> list = null;
        if(StringUtils.isBlank(menuId)){
            list = TenantContext.ignoreTenantContext(() -> {
                MenuTemp menuTemp = menuTempMapper.getLastRecord();
                return JsonUtils.parse(menuTemp.getMenuJson(), new TypeReference<List<Menu>>() {
                });
            });
        } else {
            list = TenantContext.ignoreTenantContext(() -> {
                MenuTemp menuTemp = menuTempMapper.selectByPrimaryKey(Long.parseLong(menuId));
                return JsonUtils.parse(menuTemp.getMenuJson(), new TypeReference<List<Menu>>() {
                });
            });
        }
        return list;
    }


    /**
     * 获取用户菜单
     */
    public List<UserMenuTo> getUserMenuList(String uid, Boolean isAdmin) {
        return builderUserMenuTree(getPermission(uid, isAdmin));
    }

    /**
     * 只根据uid获取用户菜单
     */
    public List<UserMenuTo> getUserMenuListNew(String uid, Boolean isAdmin) {
        // 用户拥有的权限
        List<Menu> hasPermissionMenu = getPermission(uid, isAdmin);

        return builderUserMenuTree(hasPermissionMenu);
    }




    public List<UserMenuTo> getPermissions(String uid, String userOrgId, boolean bgPermission) {
        // 用户拥有的权限
        List<Menu> hasPermissionMenu = getPermission(uid, false);
        return builderUserMenuTree(hasPermissionMenu);
    }

    /**
     * 根据前后台用户拿到各自的权限列表
     *
     * @return
     */
    public List<UserMenuTo> getPermissionByUserType() {
        return builderUserMenuTree(getAllPermission());
    }

    private List<FullMenuTo> getNeedDeleteMenu(List<FullMenuTo> menuList, List<FullMenuTo> toDeleteMenuList, Long toDeleteMenuId) {
        if (CollectionUtils.isEmpty(menuList)) {
            return toDeleteMenuList;
        }
        for (int i = 0; i < menuList.size(); i++) {
            if (menuList.get(i).getId().equals(toDeleteMenuId)) {
                toDeleteMenuList.add(menuList.get(i));
                // 将子节点全部塞入toDelete列表中
                toPlainFullMenuList(menuList.get(i).getChildren(), toDeleteMenuList);
            } else {
                // 继续递归遍历
                getNeedDeleteMenu(menuList.get(i).getChildren(), toDeleteMenuList, toDeleteMenuId);
            }
        }
        return toDeleteMenuList;
    }


    /**
     * @param needUpdateMenuList
     * @param plainMenu
     * @return
     */
    private List<UserMenuTo> toPlainList(List<UserMenuTo> needUpdateMenuList, List<UserMenuTo> plainMenu) {
        if (com.ctrip.corp.obt.generic.utils.CollectionUtils.isEmpty(needUpdateMenuList)) {
            return plainMenu;
        }
        for (int i = 0; i < needUpdateMenuList.size(); i++) {
            plainMenu.add(needUpdateMenuList.get(i));
            if (com.ctrip.corp.obt.generic.utils.CollectionUtils.isNotEmpty(needUpdateMenuList.get(i).getChildren())) {
                toPlainList(needUpdateMenuList.get(i).getChildren(), plainMenu);
            }
        }
        return plainMenu;
    }


    /**
     * @param needUpdateMenuList
     * @param plainMenu
     * @return
     */
    private List<FullMenuTo> toPlainFullMenuList(List<FullMenuTo> needUpdateMenuList, List<FullMenuTo> plainMenu) {
        if (com.ctrip.corp.obt.generic.utils.CollectionUtils.isEmpty(needUpdateMenuList)) {
            return plainMenu;
        }
        for (int i = 0; i < needUpdateMenuList.size(); i++) {
            plainMenu.add(needUpdateMenuList.get(i));
            if (com.ctrip.corp.obt.generic.utils.CollectionUtils.isNotEmpty(needUpdateMenuList.get(i).getChildren())) {
                toPlainFullMenuList(needUpdateMenuList.get(i).getChildren(), plainMenu);
            }
        }
        return plainMenu;
    }

    // /**
    //  * 校验前端传来的菜单树
    //  * @param needUpdateMenuList
    //  * @param plainMenu
    //  * @return
    //  */
    // private List<UserMenuTo> validMenuList(List<UserMenuTo> needUpdateMenuList, List<UserMenuTo> plainMenu){
    //     if (com.ctrip.corp.obt.generic.utils.CollectionUtils.isEmpty(needUpdateMenuList)){
    //         return plainMenu;
    //     }
    //     for (int i = 0; i < needUpdateMenuList.size(); i++) {
    //         plainMenu.add(needUpdateMenuList.get(i));
    //         if (com.ctrip.corp.obt.generic.utils.CollectionUtils.isNotEmpty(needUpdateMenuList.get(i).getChildren())){
    //             toPlainList(needUpdateMenuList.get(i).getChildren(), plainMenu);
    //         }
    //     }
    //     return plainMenu;
    // }


    /**
     * 将菜单列表转换为树形结构
     *
     * @param menuList 菜单列表
     * @return 树形结构
     */
    public  List<FullMenuTo> buildTree(List<Menu> menuList) {
        List<Menu> treeList = new ArrayList<>();
        Map<Long, Menu> menuMap = new HashMap<>();
        // 将所有菜单按照id存入map中
        for (Menu menu : menuList) {
            menuMap.put(menu.getId(), menu);
        }
        // 遍历所有菜单,将子菜单添加到父菜单的children中
        for (Menu menu : menuList) {
            Long parentId = menu.getParentId();
            if (parentId == 0) {
                treeList.add(menu);
            } else {
                Menu parentMenu = menuMap.get(parentId);
                if (parentMenu != null) {
                    parentMenu.getChildren().add(menu);
                }
            }
        }
        // 按照sort字段排序
        treeList.sort(Comparator.comparingInt(Menu::getSort));
        // 对每个父菜单的children排序
        treeList.forEach(this::sortChildren);
        return toMenuVo(treeList);
    }

    public  List<UserMenuTo> builderUserMenuTree(List<Menu> menuList) {
        if (CollectionUtils.isEmpty(menuList)){
            return Collections.emptyList();
        }
        List<Menu> treeList = new ArrayList<>();
        Map<Long, Menu> menuMap = new HashMap<>();
        // 将所有菜单按照id存入map中
        for (Menu menu : menuList) {
            menuMap.put(menu.getId(), menu);
        }
        // 遍历所有菜单,将子菜单添加到父菜单的children中
        for (Menu menu : menuList) {
            Long parentId = menu.getParentId();
            if (parentId == 0) {
                treeList.add(menu);
            } else {
                Menu parentMenu = menuMap.get(parentId);
                if (parentMenu != null) {
                    if (parentMenu.getChildren() == null){
                        parentMenu.setChildren(new ArrayList<>());
                    }
                    parentMenu.getChildren().add(menu);
                }
            }
        }
        // 按照sort字段排序
        treeList.sort(Comparator.comparingInt(Menu::getSort));
        // 对每个父菜单的children排序
        treeList.forEach(this::sortChildren);
        return toUserMenuTo(treeList);
    }

    public  List<FullMenuTo> toMenuVo(List<Menu> menuList){
        List<FullMenuTo> list = new ArrayList<>();
        menuList.forEach(menu -> {
            FullMenuTo menuVo = new FullMenuTo();
            menuVo.setId(menu.getId());
            menuVo.setIsParentMenu(menu.getIsParentMenu());
            menuVo.setName(menu.getName());
            menuVo.setIcon(menu.getIcon());
            menuVo.setPermission(menu.getPermission());
            menuVo.setSort(menu.getSort());
            menuVo.setType(menu.getType());
            menuVo.setParentId(menu.getParentId());
            menuVo.setUrlList(menu.getServiceUrlList());
            if (CollectionUtils.isNotEmpty(menu.getChildren())){
                menuVo.setChildren(toMenuVo(menu.getChildren()));
            }
            list.add(menuVo);
        });
        list.sort(Comparator.comparingInt(FullMenuTo::getSort));
        return list;
    }

    public  List<UserMenuTo> toUserMenuTo(List<Menu> menuList){
        List<UserMenuTo> list = new ArrayList<>();
        menuList.forEach(menu -> {
            UserMenuTo menuVo = new UserMenuTo();
            menuVo.setId(menu.getId());
            menuVo.setIsParentMenu(menu.getParentId() == 0);
            menuVo.setName(menu.getKey());
            menuVo.setIcon(menu.getIcon());
            menuVo.setPermission(menu.getPermission());
            menuVo.setSort(menu.getSort());
            menuVo.setType(com.corpgovernment.permission.entity.ResourceType.BTN.getResourceType(menu.getType()).getType());
            menuVo.setParentId(menu.getParentId());
            menuVo.setKey(menu.getIcon());
            menuVo.setLabel(menu.getName());
            menuVo.setTitle(menu.getName());
            menuVo.setCanChangeCorp(true);
            menuVo.setPath(menu.getUrl());
            if (CollectionUtils.isNotEmpty(menu.getChildren())){
                menuVo.setChildren(toUserMenuTo(menu.getChildren()));
            }
            list.add(menuVo);
        });
        list.sort(Comparator.comparingInt(UserMenuTo::getSort));
        return list;
    }

    /**
     * 对每个父菜单的children排序
     */
    private  void sortChildren(Menu menu) {
        List<Menu> children = menu.getChildren();
        if (children != null) {
            children.sort(Comparator.comparingInt(Menu::getSort));
            children.forEach(this::sortChildren);
        }
    }
    /**
     * 获取角色帐号详情
     * 如果orgId不为空,则获取父级公司的所有角色
     */
    public GetUserRoleListResponse getUserRoleDetail(GetUserRoleDetailRequest request) {
        String uid = request.getUid();
        String orgId = request.getOrgId();

        if (StringUtils.isBlank(uid)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.UID_NULL);
        }
        GetUserRoleListResponse resp = new GetUserRoleListResponse();
        List<String> orgIds = null;
        if (orgId != null) {
            MbOrgInfo parentCompany = organizationInfoService.findRecentCompanyIdByOrgId(orgId);
            if (parentCompany == null) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.GET_PARENT_ORG_INFO_IS_NULL);
            }
            orgIds = Collections.singletonList(parentCompany.getOrgId());
        }
        resp.setUserRoleListInfoList(urSrv.listUserRole(new UidOrgIdEntry(uid, orgId), orgIds).stream().map(ur -> {
            GetUserRoleListInfo urli = new GetUserRoleListInfo();
            urli.setRoleId(ur.getRoleId());
            urli.setRoleName(ur.getRoleName());
            urli.setUid(ur.getUserId());
            return urli;
        }).collect(Collectors.toList()));
        return resp;
    }

    @Autowired
    private UserRoleService urSrv;

    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    public void batchAddRoleForUser(BatchUpdateRole4UserReq req) {
        String orgIdOfEmp = req.getOrgId();
        if (CollectionUtils.isEmpty(req.getRoleInfo())) {
            MbOrgInfo parentCompany = organizationInfoService.findRecentCompanyIdByOrgId(orgIdOfEmp);
            if (parentCompany == null) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.GET_PARENT_ORG_INFO_IS_NULL);
            }
            // 删除改用户对应身份的所有角色
            userRoleMapper.deleteUserRoleByOrgId(Collections.singletonList(parentCompany.getOrgId()), req.getUids(), orgIdOfEmp);
            return;
        }
        // 删除改用户对应身份的所有角色
        userRoleMapper.deleteUserRoleByOrgId(
                req.getRoleInfo().stream().map(RoleListInfo::getOrgId).collect(Collectors.toList()),
                req.getUids(), orgIdOfEmp);

        List<MbUserRole> userRoleList = new ArrayList<>();
        for (String uId : req.getUids()) {
            userRoleList.addAll(req.getRoleInfo().stream().map(roleInfo -> {
                MbUserRole mur = new MbUserRole();
                mur.setRoleId(roleInfo.getRoleId());
                mur.setUid(uId);
                mur.setOrgId(orgIdOfEmp);
                mur.setDatachangeLasttime(new Date());
                mur.setDatachangeCreatetime(new Date());
                return mur;
            }).collect(Collectors.toList()));
        }
        userRoleMapper.insertList(userRoleList);

        // 设置管理员日志
        List<OrgPostLogVo> orgPostLogVoList = organizationEmployeeService.queryAdminLog(req.getUids(), req.getOrgId());
        if (CollectionUtils.isNotEmpty(orgPostLogVoList)) {
            OrgPostLogVo orgPostLogVo;
            for (OrgPostLogVo postLogVo : orgPostLogVoList) {
                orgPostLogVo = JsonUtils.convert(postLogVo, OrgPostLogVo.class);
                orgPostLogVo.setIsMageger("是");
            }
        }
    }

    public List<OrgAdminVo> getConfiguredUserByOrgId(String orgIdOfEmp) {
        MbOrgInfo parentCompany = organizationInfoService.findRecentCompanyIdByOrgId(orgIdOfEmp);
        if (parentCompany == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.GET_PARENT_ORG_INFO_IS_NULL);
        }
        Map<String, OrgAdminVo> map = new HashMap<>();
        userRoleMapper.listByOrgId(parentCompany.getOrgId(), orgIdOfEmp)
                .forEach(muri -> {
                    String uid = muri.getUid();
                    if (map.containsKey(uid)) {
                        map.get(uid).getRoleList().add(muri.getRoleName());
                    } else {
                        OrgAdminVo value = new OrgAdminVo();
                        value.setName(muri.getEmpName());
                        value.setPhone(muri.getEmpMobilePhone());
                        value.setUid(uid);
                        value.setRoleList(new ArrayList<>());
                        value.setAreaCode(muri.getEmpAreaCode());
                        value.getRoleList().add(muri.getRoleName());
                        map.put(uid, value);
                    }
                });
        return new ArrayList<>(map.values());
    }


    public GetUserRoleDetailResponse getBkUserRoleDetail(GetUserRoleDetailRequest request) {
        MbUserRole result = userRoleMapper.findByAccountName(request.getStaffNumber());
        if (result == null) {
            return null;
        }

        GetUserRoleDetailResponse response = new GetUserRoleDetailResponse();
        response.setId(result.getId());
        response.setStaffNumber(result.getUid());
        response.setAccountName(result.getLoginAccountName());
        response.setUserName(result.getLoginUserName());
        response.setPhone(result.getEmpMobilePhone());
        response.setRoleId(result.getRoleId());
        response.setCountryCode(result.getEmpAreaCode());
        response.setEmail(result.getEmpEmail());
        response.setPwd(result.getLoginPwd());
        response.setStatus(result.getEmpValid());

        return response;
    }

    @Transactional
    public void addOrUpdateBackgroundAccount(AddOrUpdateBackgroundAccountRequest request) {
        if (StringUtils.isBlank(request.getUserName())) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.UNAME_NULL);
        }

        MbUserRole userRole = new MbUserRole();
        userRole.setRoleId(request.getRoleId());
        userRole.setUid(request.getAccount());
        userRole.setDatachangeLasttime(new Date());
        userRole.setId(request.getId());
        if (request.getId() == null) {
            Example e = new Example(MbUserRole.class);
            e.createCriteria().andEqualTo("uid", request.getAccount());
            List<MbUserRole> urList = userRoleMapper.selectByExample(e);
            if (CollectionUtils.isNotEmpty(urList)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_ALREADY_EXISTS);
            }
            userRole.setDatachangeCreatetime(new Date());
            userRoleMapper.insert(userRole);
        } else {
            userRoleMapper.updateByPrimaryKeySelective(userRole);
        }

        MbUserLoginVo userLogin = new MbUserLoginVo();
        userLogin.setUid(request.getAccount());
        userLogin.setAccountName(request.getAccount());
        userLogin.setUserName(request.getUserName());
        userLogin.setEmail(request.getEmail());
        userLogin.setPhoneNum(request.getPhone());
        userLogin.setPwd(request.getPassword());
        userLogin.setCountryCode(request.getCountryCode());
        userLogin.setEnabled("T".equals(request.getStatus()));
        Boolean flag = userLoginService.saveOrUpdate(userLogin, true);
        if (!flag) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ACCOUNT_CREATE_ERROR);
        }

        BackgroundUserVo backgroundUserVo = new BackgroundUserVo();
        backgroundUserVo.setName(request.getUserName());
        backgroundUserVo.setUid(request.getAccount());
        backgroundUserVo.setMobilePhone(request.getPhone());
        backgroundUserVo.setValid(request.getStatus());
        backgroundUserVo.setEmail(request.getEmail());
        backgroundUserVo.setValid(request.getStatus());
        backgroundUserVo.setAreaCode(request.getCountryCode());
        flag = backgroundUserService.createOrUpdateUser(backgroundUserVo);
        if (!flag) {
            userLoginService.deleteByUid(request.getAccount());
            throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_CREATE_ERROR);
        }
    }

    public void deleteBackgroundAccount(String staffNumber) {
        JSONResult<Boolean> deleteBackgroundResult = backgroundUserSoaService.deleteUser(staffNumber);
        if (!deleteBackgroundResult.isSUCCESS()) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.DEL_EMPLOYEE_INFO_ERROR);
        }
        boolean flag = userLoginService.deleteByUid(staffNumber);
        if (!flag) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.DEL_LOGIN_INFO_ERROR);
        }
    }


    public List<Long> getUserRoleList(GetUserPermissionListRequest req) {
        return queryUidRoles(req.getUid());
    }

    public Menu getMenuByKey(String url) {
        if(StringUtils.isBlank(url)){
            return null;
        }
        List<Menu> menuList = getAllPermission();
        return menuList.stream().filter(t->url.equals(t.getUrl())).findFirst().orElse(null);
    }
}
